# encoding: utf-8
import datetime, requests, os, pexpect, traceback

from flask import request, send_from_directory
from app.extensions import log, db
from flask_restplus import Resource
from app.extensions.api import Namespace
from app.modules.common.utils import DbCommit, checkToken, recursive_json_loads
from app.modules.common.schemas import BaseSchema
from app.modules.autoTest import parameters, schemas
from app.modules.autoTest.models import PlanTest

api = Namespace('autotest', description = "自动测试")  # pylint: disable=invalid-name


@api.route('/get')
class GetRecord(Resource):
    @api.parameters(parameters.GetRecordParameters())
    @api.response(schemas.AutoTestListSchema(many = False))
    def get(self, args, **kwargs):
        """
        获取自动测试记录
        :param args:
        :return:
        """
        log.info("============== start get auto test record ==============")
        plans = args['plans']
        start_date = args['start_date']
        end_date = args['end_date']
        status = args['status']

        query = PlanTest.query.filter(PlanTest.fail.isnot(None))

        if plans is not None:
            query = query.filter(PlanTest.plan_id.in_(str(plans).split(',')))
        if start_date is not None:
            query = query.filter(PlanTest.create_time >= start_date)
        if end_date is not None:
            query = query.filter(PlanTest.create_time <= end_date)
        if status == 'SUCC':
            query = query.filter(PlanTest.fail == '0')
        if status == 'FAIL':
            query = query.filter(PlanTest.fail != '0')

        _list = query.order_by(PlanTest.create_time.desc()).all()
        return {'success': True, 'msg': '', 'data': _list}


@api.route('/do')
class DoTest(Resource):
    @api.parameters(parameters.DoTestParameters())
    @api.response(BaseSchema(many = False))
    @checkToken
    def post(self, args, **kwargs):
        """
        执行自动测试
        :param args:
        :return:
        """
        log.info("============== start do auto test ==============")
        plan_id = args['plan_id']
        plan_name = args['plan_name']
        agent_id = args['agent_id']
        agent_ip = args['agent_ip']
        case_names = args['case_names']
        case_ids = args['case_ids']
        tags = args['tags']

        if case_ids is None and tags is None:
            _msg = "测试用例和tag不能同时为空"
            log.error("============== %s ==============" % _msg)
            return {'success': False, 'msg': _msg}

        _info = PlanTest(plan_id = plan_id, plan_name = plan_name, agent_id = agent_id, agent_ip = agent_ip,
                         creater_account = kwargs['login_user_id'], creater_realname = kwargs['login_user_name'],
                         case_names = case_names, case_ids = case_ids, tags = tags)
        db.session.add(_info)

        # 请求对应agent执行测试
        _url = 'http://%s:5000/api/v1/autotest/do' % agent_ip
        _data = {"cases": case_ids, "tags": tags, "id": _info.id}
        _rtn = recursive_json_loads(requests.post(url = _url, data = _data).content)
        log.info("app.modules.autoTest.resources.DoTest 调用agent返回：%s" % _rtn)
        if not _rtn.success:
            log.error("app.modules.autoTest.resources.DoTest 调用agent异常 . %s" % _rtn)
            return _rtn
        return DbCommit()


@api.route('/update')
class UpdateTestResult(Resource):
    @api.parameters(parameters.UpdateParameters())
    @api.response(BaseSchema(many = False))
    def post(self, args, **kwargs):
        """
        更新自动测试结果
        :param args:
        :return:
        """
        log.info("============== start update auto test result ==============")
        id = args['id']
        root_case = args['root_case']
        success = args['success']
        fail = args['fail']
        report_path = args['report_path']
        desc = args['desc']

        _info = PlanTest.query.filter_by(id = id).first()
        if _info is None:
            _msg = "测试记录 %s 不存在" % id
            log.error("============== %s ==============" % _msg)
            return {'success': False, 'msg': _msg}

        if root_case is not None:
            _info.root_case = root_case
        if success is not None and fail is not None:
            _info.total = (eval(success) + eval(fail))
        if success is not None:
            _info.success = success
        if fail is not None:
            _info.fail = fail
        if report_path is not None:
            _info.report_path = report_path
        if desc is not None:
            _info.desc = desc
        return DbCommit()
